<template>
    <section>
        <!--工具条-->
        <el-col v-show="!hideToolbar" :span="24" class="toolbar">
            <el-form :inline="true">
                <el-form-item v-if="title">
                    <el-tag  type="gray">{{title}}</el-tag>
                </el-form-item>
                <el-form-item  v-for="(item,index) in filters" v-if="filters" v-show="index<showFilterCount || vCondition"  v-bind:style="filterWidth(item)"  >
                    <!--string-->
                    <el-input v-if="item.type=='string'" v-model="item.value" :placeholder="item.text"></el-input>
                    <!--checkbox-->
                    <el-tag v-if="item.type=='checkbox'" type="gray">{{item.text}}：</el-tag>
                    <span v-if="item.type=='checkbox'"  v-for="itemCb in item.value">
                        <el-checkbox v-model="itemCb[2]">{{itemCb[1]}}</el-checkbox>&nbsp
                    </span>
                    <!--datetime-->
                    <sy-dataPicker v-if="item.type=='date'" style="width: 210px"
                            v-model="item.value"
                            :placeholder="item.text">
                    </sy-dataPicker>
                    <sy-select  @change="searchChange"
                                v-if="item.type=='select'" v-model="item.value" :placeholder="item.text"
                                :valueKey="item.valueKey"  :labelKey="item.labelKey"
                                :optionData="item.data" :extendData="item.name">
                    </sy-select>
                    <!--年限的特殊处理，需要重构-->
                     <div v-if="item.type=='period'">
                         <el-date-picker :type="item.dateType" :placeholder="item.text" v-model="item.value"  style="width: 130px"></el-date-picker>
                         <span>--</span>
                         <el-date-picker :type="item.dateType" :placeholder="item.text2" v-model="item.value2"  style="width: 130px"></el-date-picker>
                     </div>
                    <!--数字范围，需要重构-->
                    <div v-if="item.type=='number'">
                        <el-input v-model="item.value" :placeholder="item.text" style="width: 80px"></el-input>
                        <span>--</span>
                        <el-input v-model="item.value2" :placeholder="item.text2" style="width: 80px"></el-input>
                    </div>
                </el-form-item>

                <el-form-item  v-if="filters">
                    <el-button v-if="filters && filters.length>showFilterCount" size="small" :icon="cdtnIcon" @click="openCondition"></el-button>
                    <el-button type="primary" size="small" @click="searchByBtn">查询</el-button>
                </el-form-item>
                <el-form-item  v-if="!hideAdd && authAdd">
                    <el-button  type="primary" size="small" @click="handleAdd">新增</el-button>
                </el-form-item>

                <el-form-item  v-if="!hideDeleteAll">
                    <el-button  type="danger" size="small" @click="handleDeleteAll">删除选中</el-button>
                </el-form-item>
                <el-form-item>
                    <slot name="extendbtnTop">
                        <!---top扩展按钮-->
                    </slot>
                </el-form-item>
            </el-form>
        </el-col>
        <!--列表-->
        <template>
            <el-table ref="table"
                      :row-style="rowStyle"
                      row-key="FID"
                      :data="listData"
                      :showHeader="!hideHeader"
                      highlight-current-row
                      v-loading="listLoading"
                      @current-change="currentChange"
                      @row-dblclick="rowDblclick"
                      :row-class-name="tableRowClassName"
                      @selection-change="handleSelectionChange"
                      :summary-method="getSummaries"
                      :show-summary="showSummary"
            >
                <el-table-column v-if="mutilSelect" type="selection" width="55">
                </el-table-column>
                <!--<el-table-column type="index" width="60">
                </el-table-column>-->
                <slot>
                    <!-- -列-->
                </slot>

                <el-table-column  min-width="130px" :fixed="fixedOperate" v-if="!hideOperate" inline-template :context="_self" align="left" label="操作">
                     <span>
                        <slot name="extendbtn" :row="row">
                            <!---扩展按钮-->
                        </slot>
                         <el-button v-if="showSelect"  type="success" size="small" style="margin-left: 0px;"  @click="handleSelect(row)">选择</el-button>
                         <!--TODO：使用row.hideEditBtn不好，污染了数据。需要重新设计-->
                         <el-button v-if="ApproveID" size="small"  style="margin-left: 0px;" @click="handleApprove(row)">{{getApproveTitle(row)}}</el-button>
                         <el-button v-if="!hideEdit && authEdit && !row.hideEditBtn" size="small"  style="margin-left: 0px;" @click="handleEdit(row)">{{getEditTitle(row)}}</el-button>
                         <DelPoperver v-if="!hideDel && authDel && !row.hideDeleteBtn"    v-on:done="handleDel(row)">删除</DelPoperver>
                        <slot name="extendbtn_end" :row="row">
                            <!---扩展按钮-->
                        </slot>
                    </span>
                </el-table-column>
            </el-table>
        </template>

        <!--分页-->

        <el-col :span="24" class="toolbar" style="padding-bottom:10px;">
            <el-pagination v-if="!hidePagination"  layout="total,prev, pager, next,jumper" @current-change="handleCurrentChange"
                           :page-size="pageSize" :total="total" style="float:right;">
            </el-pagination>
        </el-col>
    </section>
</template>

<script>
    import Vue from 'vue'
    import util from '../common/util'
    import Const from '../common/const'
    import DelPoperver from "./ctrl/DelPoperver.vue"
    export default {
        props: {
             initWhere:String, //初始化的过滤条件，重新选择查询条件后，该条件不再起作用
             fixWhere:String,  //固定的过滤条件，不管何时，查询总会带上该条件
             filters:Array,    //过滤条件的控件配置
             showFilterCount:{ //默认显示查询条件的控件数，不显示的会收起来
                 type: Number,
                 default: 100 //全部显示
             },
             listUrl:String,       //获取数据的url
             deleteUrl:String,    //删除的提交的url
             deleteAllUrl:String, //全部删除的提交的url
             editVue:String,          //编辑界面的路径
             title:String,            //标题
             rowStyle:Object,         //行样式，可用于改变行颜色
             hideToolbar:Boolean,    //是否隐藏工具栏（查询、新增等）
             hidePagination:Boolean, //是否隐藏分页
             hideHeader:Boolean,  //是否隐藏标题
             hideAdd:Boolean,     //是否隐藏新增按钮
             hideEdit:Boolean,    //是否隐藏编辑按钮
             hideDel:Boolean,     //是否隐藏删除按钮
             hideOperate:Boolean, //是否隐藏操作栏
             showSelect:Boolean,  //是否显示选择返回按钮
             showSummary:Boolean, //是否显示合计行
             mutilSelect:         //是否可多选
                 {
                     type:Boolean,
                     default:false
                 },
             fixOperate:Boolean, //是否固定操作栏
             autoSearch: {     //创建就自动查询加载数据
                    type: Boolean,
                    default: true
                 },
            pageSize: {        //分页每页条数
                type: Number,
                default: 10
            },
            ApproveID:Number,  //流程ID
            reuseEditForm:{   //编辑界面是否重复利用,是则只创建一次，性能更快。但一些状态不清除的话会共用
                type: Boolean,
                default: false
            }
        },
        watch:{
            //初始化mounted之前，watch是不会触发的
            initWhere(val){
                this.search(this.initWhere)
            },
            fixWhere(val){
                this.search(null,val)
            }
        },
        data() {
            return {
                //height:window.innerHeight*0.8,
                pickerOptions:Const.pickerOptions,
                showPage:true,
                listData: [],
                total: 0,
                page: 1,
                listLoading: false,
                where:"",
                fixWhere_:this.fixWhere, //内部变量，允许修改
                authAdd:true,
                authEdit:true,
                authDel:true,
                vCondition:false,
                cdtnIcon:"d-arrow-right",
                EditForm:null,
                multipleSelection:[],
                hideDeleteAll:true,
                sumData:null
            }
        },
        computed:{
            fixedOperate(){
                return this.fixOperate?"right":false
            }
        },
        components:{
            DelPoperver:DelPoperver
        },
        methods: {
            //----对外函数------------------
            _refrash(){
                this.search();
            },
            _search(where,fixWhere){
                this.search(where,fixWhere);
            },
            _wherePara(){
                return {
                    start: (this.page-1)*this.pageSize,
                    limit: this.pageSize,
                    where: util.joinWhere(this.fixWhere_,this.where,this.getWhere(this.filters)),
                    oWhere:this.getOWhere(this.filters)
                }
            },
            //----对外函数------------------
            filterWidth(item){
                if(item.type=='date'){
                    return  {
                        width: "210px"
                    }
                }
                if(item.type=='period'){
                    return  {
                        width: "300px"
                    }
                }
                if(item.type=='number') {
                    return  {
                        width: "180px"
                    }
                }
                else if(item.type=='checkbox'){
                    return  {
                        width: "auto"
                    }
                }
                else{
                    return  {
                        width: "130px"
                    }
                }
            },
            //获取用户列表
            search(where,fixWhere) {
                if(fixWhere!=undefined){
                    this.fixWhere_ = fixWhere
                }
                if(where!=undefined){
                    this.where = where
                }
                let para = {
                    start: (this.page-1)*this.pageSize,
                    limit: this.pageSize,
                    where: util.joinWhere(this.fixWhere_,this.where,this.getWhere(this.filters)),
                    oWhere:this.getOWhere(this.filters)
                };
                util.get(this.listUrl,para,this.switchLoading,result=> {
                    this.total = result.totalCount;
                    this.sumData = result.sumData;
                    this.listData = util.date.formatArr(result.data);
                    if(this.listData)
                    {
                        for(let row of this.listData)
                        {
                            this.$emit("onLoadRow",row)
                        }
                    }
                    this.$emit("onLoadData",this.listData)
                    //this.$emit("onLoadData",this.listData)
                    //TODO:默认选中第一行
//                    if(this.listData && this.listData.length>0) {
//                        Vue.nextTick(()=>
//                           this.$refs.table.toggleRowSelection(this.listData[0],true)
//                    }
                    //默认选中第一条
//                    if(this.listData && this.listData.length>0) {
//                        this.currentChange(this.listData[0])
//                    }
                });
            },
            onSaveSuc:function (row) {
                this.search();
            },
            switchLoading:function(flag){
               this.listLoading = flag
            },
            handleCurrentChange(val) {
                this.page = val;
                this.search();
            },
            handleSizeChange(val){
                this.pageSize = val
                this.search();
            },
            searchByBtn(e){
                this.search("");
            },
            //删除
            handleDel: function (row) {
                if(!util.emit(this,"beforeDelete",row)){
                    return;
                }
                let para = {FID:row.FID}
                util.post(this.deleteUrl,para,this.switchLoading,result=> {
                    util.msgSuc("删除成功")
                    this.search()
                    this.$emit("afterDelete",row)
                })
            },
            //多选删除
            handleDeleteAll: function(){
                let FIDS='';
                for(let item of this.multipleSelection){
                     FIDS += item.FID+',';
                }
                FIDS = FIDS.toString().substring(0,FIDS.toString().length-1);
                if(!util.emit(this,"beforeDeleteAll",FIDS)){
                    return;
                }
                let para = {FIDS:FIDS}
                this.$confirm('删除后不可恢复，确认删除吗?', '提示', {
                    //type: 'warning'
                }).then(()=>{
                util.post(this.deleteAllUrl,para,this.switchLoading,result=> {
                   util.msgSuc("删除成功")
                   this.search()
                   this.$emit("afterDeleteAll",FIDS)
               })}).catch(() => {

                });
            },
            //显示编辑界面
            handleEdit: function (row) {
                if(!util.emit(this,"beforeEdit",row)){
                    return;
                }
                this.createEditForm()._openEdit(row,this.authEdit);
            },
            //显示新增界面
            handleAdd: function () {
                var row = {};
                if(!util.emit(this,"beforeAdd",row)){
                    return;
                }
                this.createEditForm()._openAdd(row,this.authAdd)
            },
            handleSelect:function (row) {
                this.$emit("onSelect",row)
            },
            currentChange(row,oldRow){
                this.$emit("current-change",row,oldRow)
            },
            rowDblclick(row){
                if(this.showSelect) {
                    this.$emit("onSelect", row)
                }
            },
            tableRowClassName(row, index) {
                var r = {};
                util.emit(this,"row-class-name",row,index,r)
                return r.className;
            },
            //特殊条件，以key:value传到服务端，再在服务端构造
            getOWhere(filters){
                let result = {}
                if(filters) {
                    for (let i = 0; i < filters.length; i++) {
                        let item = filters[i];
                        if (item.value && item.remote) {
                            result[item.name] = item.value
                        }
                    }
                }
                return result
            },
            isEmpty(item){
                if(item.type == "number"){
                    return (item.value===undefined || item.value==="" || item.value===null)
                       && (item.value2===undefined || item.value2==="" || item.value2===null)
                }else  if(item.type == "period"){
                    return (item.value===undefined || item.value==="" || item.value===null)
                        || (item.value2===undefined || item.value2==="" || item.value2===null)
                }
                else{
                    return item.value===undefined || item.value==="" || item.value===null
                }
            },
            //构造查询条件
            getWhere(filters) {
                //TODO:安全起见，需要到移动服务端去实现
                let result =  ""
                if(filters){
                    for(let i=0;i<filters.length;i++){
                        let item = filters[i];
                        if(!this.isEmpty(item)) {
                            if(item.remote){  //特殊条件，以key:value传到服务端，再在服务端
                                continue
                            }
                            if (item.type == "string") {
                                result = util.joinWhere(result,item.name + " like '%" + item.value + "%'")
                            } else if (item.type == "select") {
                                if(item.equal=="like"){
                                    result = util.joinWhere(result,item.name + " like '%" + item.value + "%'")
                                }else {
                                    let a = typeof(item.value)=="string"?"'" + item.value + "'": item.value
                                    result = util.joinWhere(result, item.name + "=" + a)
                                }
                            } else if (item.type == "date") {
                                if(item.value[0] && item.value[1]) {
                                    let bDate = util.date.format(item.value[0], 'yyyy-MM-dd')
                                    let eDate = util.date.format(item.value[1], 'yyyy-MM-dd 23:59:59')
                                    result = util.joinWhere(result,item.name + ">='" + bDate + "' and " + item.name + "<'" + eDate + "'")
                                }
                            } else if (item.type == "period") {
                                if(item.value2){
                                    let bDate = util.date.format(item.value, 'yyyy-MM-dd')
                                    let eDate = util.date.format(item.value2, 'yyyy-MM-dd 23:59:59')
                                    //有交集就查出来
                                    let s = "not(" + item.name + ">='" + eDate + "' or " + item.name2 + "<'" + bDate + "')"
                                    result = util.joinWhere(result,s)
                                }
                            }
                            else if (item.type == "checkbox") {
                                let checks = [];
                                for(let i=0;i<item.value.length;i++) {
                                    if(item.value[i][2]){
                                        let a = typeof(item.value[i][0])=="string"?"'" + item.value[i][0] + "'": item.value[i][0]
                                        checks.push(a)
                                    }
                                }
                                if(checks.length>0){
                                    result = util.joinWhere(result, item.name + " in(" + checks.join(",") + ")")
                                }
                            }else if(item.type == 'number'){
                                //有交集就查出来
                                //TODO:要注意0也要包含
                                if(item.value || item.value==0){
                                    result = util.joinWhere(result,item.name + ">=" + item.value)
                                }
                                if(item.value2 || item.value==0){
                                    result = util.joinWhere(result,item.name + "<=" + item.value2)
                                }
                            }
                        }
                    }
                }
                return result;
            },
            searchChange(val,record,key){
                this.$emit("searchChange",key,val,record)
            },
            openCondition(){
                this.vCondition = !this.vCondition
                if (this.cdtnIcon == "d-arrow-left") {
                    this.cdtnIcon = "d-arrow-right"
                }else{
                    this.cdtnIcon = "d-arrow-left"
                }
            },
            createEditForm(){
                if(this.EditForm){
                    return this.EditForm
                }
                if(this.editVue) {
                    let C = Vue.extend(require(this.editVue))
                    let form = new C()
                    form.$on("onSaveSuc", this.onSaveSuc)
                    this.$el.appendChild(form.$mount().$el)
                    if(this.reuseEditForm){
                        this.EditForm = form
                    }else{
                        //form子组件为el-dialog
                        //这里要销毁，以免使用相同窗体，状态保留出错
                        form.$children[0].$on("close",()=>{
                            form.$destroy(true);
                            this.$el.removeChild(form.$el);
                        })
                    }
                    return form
                }
                return null
            },
            handleSelectionChange(val) {
                this.multipleSelection = val;
                 if(this.multipleSelection.length!=0)
                 {
                     this.hideDeleteAll = false;
                 }
                 else
                 {
                     this.hideDeleteAll = true;
                 }
            },
            getEditTitle(row){
                if(row.editTitle)
                {
                   return row.editTitle
                }
                if(this.authEdit)
                {
                    return "编辑"
                } else {
                    return "查看"
                }
            },
            getSummaries(param){
                  if(!this.showSummary) {
                     return []
                 }
                let result = []
                const { columns, data } = param;
                columns.forEach((column, index) => {
                    let r ={}
                    //this.$emit("onSum",column.property,this._wherePara(),r)
                    if(this.sumData && this.sumData[column.property]){
                         result[index] = this.sumData[column.property]
                    }else if (index === 0) {
                        result[index] = '合计'
                    }else {
                        result[index] = ''
                    }
                })
                return result
            },
            getApproveTitle(row){
                if(row.ApproveTitle)
                {
                    return row.ApproveTitle
                }
                if(row.FApproveStatus==0) {
                    return "提交审核"
                }
                return "审核"
            },
            handleApprove(row){
                if(!util.emit(this,"beforeApprove",row)){
                    return;
                }
                this.createEditForm()._openApprove(row,this.ApproveID);
            }
        },
        created(){
            if(!util.hasAuth("add")){
                this.authAdd = false
            }
            if(!util.hasAuth("modify")){
                this.authEdit = false
            }
            if(!util.hasAuth("delete")){
                this.authDel = false
            }
            if(this.autoSearch) {
                this.search(this.initWhere)
            }
        }
    }
</script>
